package com.tubang.logistics.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.tubang.common.util.BeanMapper;
import com.tubang.common.util.CollectionUtils;
import com.tubang.common.util.IdGenerator;
import com.tubang.logistics.entity.InvoiceEntity;
import com.tubang.logistics.entity.LogisticsBill;
import com.tubang.logistics.entity.LogisticsSett;
import com.tubang.logistics.exception.BizException;
import com.tubang.logistics.mapper.LogisticsBillMapper;
import com.tubang.logistics.mapper.LogisticsSettMapper;
import com.tubang.logistics.service.IFinanceService;
import com.tubang.logistics.service.IInvoiceService;
import com.tubang.logistics.service.ILogisticsSettService;
import com.tubang.logistics.util.DateUtils;
import com.tubang.logistics.util.ExcelUtils;
import com.tubang.logistics.vo.finance.*;
import com.tubang.logistics.vo.statistics.OrderTableVO;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class FinanceServiceImpl implements IFinanceService {

	@Autowired
	private LogisticsBillMapper logisticsBillMapper;
	@Autowired
	private LogisticsSettMapper logisticsSettMapper;
	@Autowired
	private ILogisticsSettService iLogisticsSettService;
	@Autowired
	private IInvoiceService iInvoiceService;

	@Override
	public Map<String, Object> listBillStatistics(Long startTime, Long endTime, String userId, boolean get, Integer page, Integer rows) {
		Map<String, Object> result = new HashMap<>();
		Map<String, Object> resultList = new HashMap<>();

		Date startDate = new Date(startTime);
		Date endDate = new Date(endTime);

		PageHelper.startPage(page, rows);
		List<FinanceVO> financeVOList = logisticsBillMapper.listBill(startDate, endDate, userId, get);
		Page pageBean = (Page) financeVOList;

		FinanceSimpleVO count = logisticsBillMapper.countBill(startDate, endDate, userId, get);
		resultList.put("list", financeVOList);
		resultList.put("count", count);

		result.put("total", pageBean.getTotal());
		result.put("result", resultList);
		return result;
	}

	@Override
	public Map<String, Object> listBillTable(Long startTime, Long endTime, String userId, boolean get, String content, Integer page, Integer rows) {
		Map<String, Object> result = new HashMap<>();
		Map<String, Object> resultList = new HashMap<>();

		Date startDate = new Date(startTime);
		Date endDate = new Date(endTime);

		PageHelper.startPage(page, rows);
		List<FinanceTableVO> financeTableVOS = logisticsBillMapper.listBillTable(startDate, endDate, userId, get, content);
		Page pageBean = (Page) financeTableVOS;

		FinanceSimpleVO financeSimpleVO = logisticsBillMapper.getBillTotal(startDate, endDate, userId, get, content);

		financeTableVOS.forEach(financeTableVO -> financeTableVO.setFinishTimeName(DateUtils.getyyyyMMddHHmmss(financeTableVO.getFinishTime())));

		resultList.put("list", financeTableVOS);
		resultList.put("count", financeSimpleVO);

		result.put("total", pageBean.getTotal());
		result.put("result", resultList);
		return result;
	}

	@Override
	public Map<String, Object> listSettle(Long startTime, Long endTime, String userId, boolean get, boolean receive, Integer page, Integer rows) {
		Map<String, Object> result = new HashMap<>();
		Map<String, Object> resultList = new HashMap<>();

		Date startDate = new Date(startTime);
		Date endDate = new Date(endTime);

		PageHelper.startPage(page, rows);
		List<FinanceVO> financeVOList = logisticsSettMapper.listSettle(startDate, endDate, userId, get, receive);
		Page pageBean = (Page) financeVOList;

		FinanceSimpleVO count = logisticsSettMapper.countSettle(startDate, endDate, userId, get, receive);
		resultList.put("list", financeVOList);
		resultList.put("count", count);

		result.put("total", pageBean.getTotal());
		result.put("result", resultList);
		return result;
	}

	@Override
	public Map<String, Object> listSettleTable(Long startTime, Long endTime, String userId, boolean get, boolean receive, String content, Integer page, Integer rows) {
		Map<String, Object> result = new HashMap<>();
		Map<String, Object> resultList = new HashMap<>();

		Date startDate = new Date(startTime);
		Date endDate = new Date(endTime);

		PageHelper.startPage(page, rows);
		List<FinanceTableVO> financeTableVOS = logisticsSettMapper.listSettleTable(startDate, endDate, userId, get, receive, content);
		Page pageBean = (Page) financeTableVOS;

		financeTableVOS.forEach(financeTableVO -> financeTableVO.setFinishTimeName(DateUtils.getyyyyMMddHHmmss(financeTableVO.getFinishTime())));

		FinanceSimpleVO financeSimpleVO = logisticsSettMapper.getSettleTotal(startDate, endDate, userId, get, receive, content);

		resultList.put("list", financeTableVOS);
		resultList.put("count", financeSimpleVO);

		result.put("total", pageBean.getTotal());
		result.put("result", resultList);
		return result;
	}

	@Override
	public Map<String, Object> listBill(Long startTime, Long endTime, String userId, Integer financeStatus, String content, Integer page, Integer rows) {
		Map<String, Object> result = new HashMap<>();

		Date startDate = null;
		Date endDate = null;
		if (null != startTime) {
			startDate = new Date(startTime);
			endDate = new Date(endTime);
		}

		PageHelper.startPage(page, rows);
		List<BillListVO> billListVOS = logisticsBillMapper.listBillForCheck(startDate, endDate, userId, financeStatus, content);
		Page pageBean = (Page) billListVOS;

		billListVOS.forEach(billListVO -> billListVO.setCreateTimeName(DateUtils.getyyyyMMddHHmmss(billListVO.getCreateTime())));

		result.put("result", billListVOS);
		result.put("total", pageBean.getTotal());
		return result;
	}

	@Override
	public void updateBill(BillUpdateVO billUpdateVO) {
		logisticsBillMapper.updateBillById(billUpdateVO);
		if (null != billUpdateVO.getInvoice()) {
			LogisticsBill logisticsBill = logisticsBillMapper.selectByPrimaryKey(billUpdateVO.getId());
			InvoiceEntity invoiceEntity = new InvoiceEntity();
			invoiceEntity.setNum(IdGenerator.INSTANCE.nextId());
			invoiceEntity.setBillId(logisticsBill.getId());
			invoiceEntity.setBillNum(logisticsBill.getNum());
			invoiceEntity.setUserId(logisticsBill.getUserId());
			invoiceEntity.setUserName(logisticsBill.getUserName());
			invoiceEntity.setCarrierId(logisticsBill.getCarrierId());
			invoiceEntity.setCarrierName(logisticsBill.getCarrier());
			invoiceEntity.setMoney(new BigDecimal(logisticsBill.getMoneyAmount()));
			invoiceEntity.setCreateTime(new Date());
			iInvoiceService.insertOrUpdate(invoiceEntity);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void insertSettle(List<String> ids) {
		List<LogisticsBill> logisticsBills = logisticsBillMapper.listByIds(ids);

		if (!CollectionUtils.isEmpty(logisticsBills)) {
			String userName = logisticsBills.get(0).getUserName();
			String carrierName = logisticsBills.get(0).getCarrier();
			BigDecimal moneyCash = BigDecimal.ZERO;
			BigDecimal moneyAg = BigDecimal.ZERO;
			BigDecimal moneyTra = BigDecimal.ZERO;
			BigDecimal moneyOth = BigDecimal.ZERO;
			BigDecimal moneyAmount = BigDecimal.ZERO;
			BigDecimal weight = BigDecimal.ZERO;
			for (LogisticsBill logisticsBill : logisticsBills) {
				if (!userName.equals(logisticsBill.getUserName()) || !carrierName.equals(logisticsBill.getCarrier()))
					throw new BizException(BizException.DEFULT_BIZ_CODE, "收款方必须是同一人");
				if (null != logisticsBill.getSettId())
					throw new BizException(BizException.DEFULT_BIZ_CODE, "一个账单只能生成一次结算单");
				moneyCash = moneyCash.add(new BigDecimal(logisticsBill.getMoneyCash()));
				moneyAg = moneyAg.add(new BigDecimal(logisticsBill.getMoneyAg()));
				moneyTra = moneyTra.add(new BigDecimal(logisticsBill.getMoneyTra()));
				moneyOth = moneyOth.add(new BigDecimal(logisticsBill.getMoneyOth()));
				moneyAmount = moneyAmount.add(new BigDecimal(logisticsBill.getMoneyAmount()));
				weight = weight.add(new BigDecimal(logisticsBill.getGoodsWeight()));
			}

			LogisticsBill logisticsBill = logisticsBills.get(0);
			LogisticsSett logisticsSett = new LogisticsSett();
			logisticsSett.setId(null);
			logisticsSett.setNum(IdGenerator.INSTANCE.nextId());
			logisticsSett.setUserName(logisticsBill.getUserName());
			logisticsSett.setUserMobile(logisticsBill.getUserMobile());
			logisticsSett.setUserId(logisticsBill.getUserId());
			logisticsSett.setMoneyCash(moneyCash.doubleValue());
			logisticsSett.setMoneyAg(moneyAg.doubleValue());
			logisticsSett.setMoneyTra(moneyTra.doubleValue());
			logisticsSett.setMoneyOth(moneyOth.doubleValue());
			logisticsSett.setMoneyAmount(moneyAmount.doubleValue());
			logisticsSett.setWeight(weight.doubleValue());
			logisticsSett.setUserId(logisticsBill.getUserId());
			logisticsSett.setUserName(logisticsBill.getUserName());
			logisticsSett.setCarrier(logisticsBill.getCarrier());
			logisticsSett.setCarrierId(logisticsBill.getCarrierId());
			logisticsSett.setUserMobile(logisticsBill.getUserMobile());
			logisticsSett.setCarrierMobile(logisticsBill.getCarrierMobile());
			logisticsSett.setCreateTime(new Date());
			iLogisticsSettService.insertOrUpdate(logisticsSett);

			logisticsBillMapper.updateSettIdByIds(logisticsSett.getId(), ids);

		}

	}

	@Override
	public BillDetailVO getBillDetail(String id) {
		return logisticsBillMapper.getDetailById(id);
	}

	@Override
	public Map<String, Object> listSettleForCheck(Long startTime, Long endTime, String userId, String content, Integer status, boolean carrier, Integer page, Integer rows) {
		Map<String, Object> result = new HashMap<>();

		Date startDate = null;
		Date endDate = null;
		if (null != startTime) {
			startDate = new Date(startTime);
			endDate = new Date(endTime);
		}

		PageHelper.startPage(page, rows);
		List<SettleListVO> settleListVOS = logisticsSettMapper.listSettleForCheck(startDate, endDate, userId, content, status, carrier);
		Page pageBean = (Page) settleListVOS;

		settleListVOS.forEach(billListVO -> billListVO.setCreateTimeName(DateUtils.getyyyyMMddHHmmss(billListVO.getCreateTime())));

		result.put("result", settleListVOS);
		result.put("total", pageBean.getTotal());
		return result;
	}

	@Override
	public List<SettleDetailVO> getSettleDetail(String id) {
		List<SettleDetailVO> settleDetailVOS = logisticsBillMapper.listSettleDetailById(id);

		settleDetailVOS.forEach(settleDetailVO -> settleDetailVO.setCreateTimeName(DateUtils.getyyyyMMddHHmmss(settleDetailVO.getCreateTime())));
		return settleDetailVOS;
	}

	@Override
	public HSSFWorkbook exportBill(Long startTime, Long endTime, String userId, boolean get, String content) {
		Date startDate = new Date(startTime);
		Date endDate = new Date(endTime);

		List<FinanceTableVO> financeTableVOS = logisticsBillMapper.listBillTable(startDate, endDate, userId, get, content);

		//excel内容
		String[][] excelContent = new String[financeTableVOS.size() + 1][7];

		//表头
		excelContent[0][0] = "订单号";
		excelContent[0][1] = "付款方";
		excelContent[0][2] = "付款方联系电话";
		excelContent[0][3] = "运单运量（顿）";
		excelContent[0][4] = "运单金额（元）";
		excelContent[0][5] = "线上结算运费（元）";
		excelContent[0][6] = "运输完成时间";


		//内容
		for (int i = 1; i < financeTableVOS.size() + 1; i++) {
			FinanceTableVO financeTableVO = financeTableVOS.get(i - 1);
			excelContent[i][0] = financeTableVO.getOrderSn();
			excelContent[i][1] = financeTableVO.getUserName();
			excelContent[i][2] = financeTableVO.getUserMobile();
			excelContent[i][3] = null != financeTableVO.getWeight() ? financeTableVO.getWeight().toPlainString() : null;
			excelContent[i][4] = null != financeTableVO.getMoney() ? financeTableVO.getMoney().toPlainString() : null;
			excelContent[i][5] = null != financeTableVO.getMoney() ? financeTableVO.getMoney().toPlainString() : null;
			excelContent[i][6] = DateUtils.getyyyyMMddHHmmss(financeTableVO.getFinishTime());

		}

		//poi
		return ExcelUtils.createMoreSheetHSSFWorkbook(excelContent);
	}

	@Override
	public HSSFWorkbook exportSettle(Long startTime, Long endTime, String userId, boolean get, boolean receive, String content) {
		Date startDate = new Date(startTime);
		Date endDate = new Date(endTime);

		List<FinanceTableVO> financeTableVOS = logisticsSettMapper.listSettleTable(startDate, endDate, userId, get, receive, content);

		//excel内容
		String[][] excelContent = new String[financeTableVOS.size() + 1][7];

		//表头
		excelContent[0][0] = "订单号";
		excelContent[0][1] = "付款方";
		excelContent[0][2] = "付款方联系电话";
		excelContent[0][3] = "总运费(元)";
		excelContent[0][4] = "现金金额（元）";
		excelContent[0][5] = "开票金额（元）";
		excelContent[0][6] = "运输完成时间";


		//内容
		for (int i = 1; i < financeTableVOS.size() + 1; i++) {
			FinanceTableVO financeTableVO = financeTableVOS.get(i - 1);
			excelContent[i][0] = financeTableVO.getOrderSn();
			excelContent[i][1] = financeTableVO.getUserName();
			excelContent[i][2] = financeTableVO.getUserMobile();
			excelContent[i][3] = null != financeTableVO.getMoney() ? financeTableVO.getMoney().toPlainString() : null;
			excelContent[i][4] = null != financeTableVO.getMoney() ? financeTableVO.getMoney().toPlainString() : null;
			excelContent[i][5] = null != financeTableVO.getMoney() ? financeTableVO.getMoney().toPlainString() : null;
			excelContent[i][6] = DateUtils.getyyyyMMddHHmmss(financeTableVO.getFinishTime());

		}

		//poi
		return ExcelUtils.createMoreSheetHSSFWorkbook(excelContent);
	}

	@Override
	public void updateSettle(String id) {
		LogisticsSett logisticsSett = new LogisticsSett();
		logisticsSett.setId(id);
		logisticsSett.setStatusCode("1");
		logisticsSettMapper.updateById(logisticsSett);
	}
}
